"""
配置管理器
负责加载、验证和管理FMCW雷达系统的配置参数
"""

import json
import os
import logging
from typing import Dict, Any, Optional
from pathlib import Path


class ConfigManager:
    """配置文件管理器"""
    
    def __init__(self, config_path: str = "config/config.json"):
        """
        初始化配置管理器
        
        Args:
            config_path: 配置文件路径
        """
        self.config_path = Path(config_path)
        self.config: Dict[str, Any] = {}
        self.logger = logging.getLogger(__name__)
        
    def load_config(self) -> Dict[str, Any]:
        """
        加载配置文件
        
        Returns:
            配置字典
            
        Raises:
            FileNotFoundError: 配置文件不存在
            json.JSONDecodeError: 配置文件格式错误
            ValueError: 配置验证失败
        """
        if not self.config_path.exists():
            raise FileNotFoundError(f"配置文件不存在: {self.config_path}")
        
        try:
            with open(self.config_path, 'r', encoding='utf-8') as f:
                self.config = json.load(f)
            
            self._validate_config()
            self.logger.info(f"成功加载配置文件: {self.config_path}")
            return self.config
            
        except json.JSONDecodeError as e:
            raise json.JSONDecodeError(f"配置文件JSON格式错误: {e}", e.doc, e.pos)
    
    def _validate_config(self) -> None:
        """
        验证配置文件内容
        
        Raises:
            ValueError: 配置验证失败
        """
        required_sections = ['instruments', 'fmcw_signal', 'trigger', 'output', 'logging']  # 移除analysis节，已简化系统
        
        for section in required_sections:
            if section not in self.config:
                raise ValueError(f"配置文件缺少必需的节: {section}")
        
        # 验证仪器配置
        instruments = self.config['instruments']
        if 'smw' not in instruments:
            raise ValueError("缺少SMW信号发生器配置")
        if 'fsw' not in instruments:
            raise ValueError("缺少FSW频谱分析仪配置")
        
        # 验证IP地址格式
        for instrument_name, instrument_config in instruments.items():
            if 'ip' not in instrument_config:
                raise ValueError(f"{instrument_name.upper()}仪器缺少IP地址配置")
            self._validate_ip_address(instrument_config['ip'])
        
        # 验证FMCW信号参数
        fmcw_config = self.config['fmcw_signal']
        required_fmcw_params = ['bandwidth', 'sweep_rate', 'scale_factor']
        for param in required_fmcw_params:
            if param not in fmcw_config:
                raise ValueError(f"FMCW信号配置缺少参数: {param}")
        
        # 验证快慢时间配置（如果存在）
        if 'fast_slow_time' in self.config:
            fast_slow_config = self.config['fast_slow_time']
            required_fast_slow_params = ['fast_time_start_offset', 'fast_time_window', 'enable_processing']
            for param in required_fast_slow_params:
                if param not in fast_slow_config:
                    raise ValueError(f"快慢时间配置缺少参数: {param}")
            
            # 验证fmcw_signal配置是否存在（用于时序计算）
            fmcw_config = self.config.get('fmcw_signal', {})
            if fast_slow_config.get('enable_processing', False):
                required_fmcw_timing_params = ['bandwidth', 'sweep_rate']
                if fmcw_config.get('waveform_type', 'linear') == 'triangular':
                    required_fmcw_timing_params.extend(['down_bandwidth', 'down_sweep_rate'])
                
                for param in required_fmcw_timing_params:
                    if param not in fmcw_config:
                        raise ValueError(f"启用快慢时间处理时，FMCW信号配置缺少时序计算参数: {param}")
        
        # 验证触发器配置
        trigger_config = self.config['trigger']
        required_trigger_params = ['source', 'slope', 'level', 'timeout']
        for param in required_trigger_params:
            if param not in trigger_config:
                raise ValueError(f"触发器配置缺少参数: {param}")
        
        # 验证触发源
        valid_sources = ['EXT', 'RFPO', 'IMM']
        if trigger_config['source'].upper() not in valid_sources:
            raise ValueError(f"无效的触发源: {trigger_config['source']}，有效值: {valid_sources}")
        
        # 验证触发斜率
        valid_slopes = ['POS', 'NEG']
        if trigger_config['slope'].upper() not in valid_slopes:
            raise ValueError(f"无效的触发斜率: {trigger_config['slope']}，有效值: {valid_slopes}")
        
        self.logger.info("配置文件验证通过")
    
    def _validate_ip_address(self, ip: str) -> None:
        """
        验证IP地址格式
        
        Args:
            ip: IP地址字符串
            
        Raises:
            ValueError: IP地址格式无效
        """
        parts = ip.split('.')
        if len(parts) != 4:
            raise ValueError(f"无效的IP地址格式: {ip}")
        
        try:
            for part in parts:
                num = int(part)
                if not 0 <= num <= 255:
                    raise ValueError(f"IP地址段超出范围: {num}")
        except ValueError:
            raise ValueError(f"IP地址包含非数字字符: {ip}")
    
    def get(self, key_path: str, default: Any = None) -> Any:
        """
        获取配置值，支持点号分隔的嵌套键路径
        
        Args:
            key_path: 配置键路径，如 'instruments.smw.ip'
            default: 默认值
            
        Returns:
            配置值
        """
        keys = key_path.split('.')
        value = self.config
        
        try:
            for key in keys:
                value = value[key]
            return value
        except (KeyError, TypeError):
            return default
    
    def set(self, key_path: str, value: Any) -> None:
        """
        设置配置值
        
        Args:
            key_path: 配置键路径
            value: 配置值
        """
        keys = key_path.split('.')
        config = self.config
        
        # 导航到目标位置
        for key in keys[:-1]:
            if key not in config:
                config[key] = {}
            config = config[key]
        
        # 设置值
        config[keys[-1]] = value
    
    def save_config(self, output_path: Optional[str] = None) -> None:
        """
        保存配置到文件
        
        Args:
            output_path: 输出文件路径，默认为原配置文件路径
        """
        save_path = Path(output_path) if output_path else self.config_path
        
        try:
            # 确保目录存在
            save_path.parent.mkdir(parents=True, exist_ok=True)
            
            with open(save_path, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, indent=2, ensure_ascii=False)
            
            self.logger.info(f"配置已保存到: {save_path}")
            
        except Exception as e:
            self.logger.error(f"保存配置文件失败: {e}")
            raise
    
    def get_instrument_config(self, instrument: str) -> Dict[str, Any]:
        """
        获取仪器配置
        
        Args:
            instrument: 仪器名称 ('smw' 或 'fsw')
            
        Returns:
            仪器配置字典
        """
        return self.get(f'instruments.{instrument}', {})
    
    def get_fmcw_config(self) -> Dict[str, Any]:
        """
        获取FMCW信号配置
        
        Returns:
            FMCW配置字典
        """
        return self.get('fmcw_signal', {})
    
    def get_trigger_config(self) -> Dict[str, Any]:
        """
        获取触发器配置
        
        Returns:
            触发器配置字典
        """
        return self.get('trigger', {})
    
    def get_analysis_config(self) -> Dict[str, Any]:
        """
        获取分析配置（兼容性方法，返回空配置）
        
        Returns:
            分析配置字典（空）
        """
        return {}  # 已移除analysis配置，返回空字典保持兼容性
    
    def get_output_config(self) -> Dict[str, Any]:
        """
        获取输出配置
        
        Returns:
            输出配置字典
        """
        return self.get('output', {})
    
    def get_logging_config(self) -> Dict[str, Any]:
        """
        获取日志配置
        
        Returns:
            日志配置字典
        """
        return self.get('logging', {})
    
    def get_fast_slow_time_config(self) -> Dict[str, Any]:
        """
        获取快慢时间采集配置
        
        Returns:
            快慢时间采集配置字典
        """
        return self.get('fast_slow_time', {})